/*=============================================================================
*
*   Copyright (C) 2020 All rights reserved.
*
*   Filename:		test_sif.cpp
*
*   Author: Wang Zhecheng - wangzhecheng@yeah.net
*
*   Date: 2020-02-20 21:23
*
*   Last Editors: Wang Zhecheng - wangzhecheng@yeah.net
*
*   Last modified:	2020-08-04 01:22
*
*   Description:
*
=============================================================================*/
#include "../../include/fem.hpp"
#include "../../include/geometry/shape/subdivide.hpp"
#include "../../include/implicit_solver.hpp"
#include "../../include/incremental_load.hpp"
#include "../../include/io/data_extractor.hpp"
#include "../../include/io/vtu_writer.hpp"
#include "../../include/model/model.hpp"
#include "../../include/solid.hpp"
#include "../../include/static_equation.hpp"
#include "../../include/xfem/levelset.hpp"
#include <boost/geometry.hpp>

LOGGING_REGISTER()

void incline_centre_crack(const std::filesystem::path& input_file_name,
                          const int&                   degree = 0,
                          const _real&                 length = 0.0254) {
  using namespace geoxfem;

  using MethodPolicy   = model::fem;
  using CouplePolicy   = model::solid;
  using DimensionType  = geometry::plane_strain;
  using EquationPolicy = model::static_equation;
  using SolvePolicy    = model::implicit_solver;
  using LoadPolicy     = model::incremental_load;
  using Model =
    geoxfem::model::Model<MethodPolicy, CouplePolicy, DimensionType,
                          EquationPolicy, SolvePolicy, LoadPolicy, mpl2>;

  constexpr size_t dimension = traits::dimension<DimensionType>::value;

  /*  detail, trace, process, info, warning, debug, error }; */
  geoxfem::log::log_init(geoxfem::log::severity_level::error);

  using point_type = traits::point_type<DimensionType>::type;
  /* using Gauss = model::GaussPoint<Shape>; */
  /* using Segment = geometry::Segment<MethodPolicy, DimensionType, mpl1>; */

  io::DataParser<io::json> parser;
  parser.read(input_file_name);

  io::DataWriter<Model, io::vtu> writer;
  writer.init(parser.getPath(), parser.getFileName());

  Model model;
  model.append(&writer);

  model.init(parser);
  model.buildProblem();
  ////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////

  _real radian = degree * deg_to_rad;

  VectorXR coord0(dimension);
  coord0 << length / 2. * cos(radian), length / 2. * sin(radian) + 0.01;
  VectorXR coord1(dimension);
  coord1 << -length / 2. * cos(radian), -length / 2. * sin(radian) + 0.01;
  /* xfem::initialCrack("segment", coord0, coord1, model); */

  /* io::DataPloter ploter; */
  /* model.plot(ploter); */

  std::cout << algorithm::integral(*model.getMesh(), [](const auto&) {
    return 1;
  }) << std::endl;
  ////////////////////////////////////////////////////////////////
  ////////////////////////////////////////////////////////////////

  model.solveProblem();
}

int main(int argc, char* argv[]) {
  using namespace geoxfem;

  /* std::string input_file_name = */
  /*   argc < 2 ? */
  /* "test/test_sif/incline_centre_crack5x5.json" */
  /* "test/test_sif/incline_centre_crack10x10.json" */
  /* "test/test_sif/incline_centre_crack40x40.json" */
  /* : argv[1]; */

  int degree = 30;

  std::string input_file_name;

  /* input_file_name = "test/test_sif/incline_centre_crack5x5.json"; */
  /* incline_centre_crack(input_file_name, degree, 0.1); */
  /* input_file_name = "test/test_sif/incline_centre_crack10x10.json"; */
  /* incline_centre_crack(input_file_name, degree, 0.1); */
  /* input_file_name = "test/test_sif/incline_centre_crack20x20.json"; */
  /* incline_centre_crack(input_file_name, degree, 0.1); */
  /* input_file_name = "test/test_sif/incline_centre_crack40x40.json"; */
  /* incline_centre_crack(input_file_name, degree, 0.1); */
  /* input_file_name = "test/test_sif/incline_centre_crack20x20tri.json"; */
  /* incline_centre_crack(input_file_name, degree, 0.1); */
  input_file_name = "test/test_sif/incline_centre_crack20x20_quad_tri.json";
  incline_centre_crack(input_file_name, degree, 0.1);
  /* for(size_t i = 0; i < 91; i += 5) { */
  /*   Segment foo(input_file_name); */
  /* } */

  return 0;
}
